package service

import (
	"context"
	"fmt"
	"math/rand"
	"regexp"
	"strconv"
	"time"
	"user-srv/basic/config"
	__ "user-srv/basic/proto"
	"user-srv/handler/model"
	"user-srv/pkg/dx"
	"user-srv/pkg/jwt"
	"user-srv/pkg/md5"
)

type Server struct {
	__.UnimplementedUserServer
}

// SendSms 验证码发送
func (s *Server) SendSms(_ context.Context, in *__.SendSmsReq) (*__.SendSmsResp, error) {
	//参数格式校验
	if in.Phone == "" {
		return nil, fmt.Errorf("手机号不能为空")
	}
	//手机号格式校验
	if !regexp.MustCompile(`^1[3-9]\d{9}$`).MatchString(in.Phone) {
		return nil, fmt.Errorf("手机号格式不对,请重新输入")
	}
	//获取发送次数
	count, _ := config.Rdb.Get(config.Ctx, "send:smsNumber"+in.Phone).Int()
	if count >= 3 {
		return nil, fmt.Errorf("同一手机号5分钟内最多发送3条验证码")
	}
	//生成6位数验证码
	code := rand.Intn(900000) + 100000
	CodeKey := "SendSms:" + in.Phone
	//验证码如缓存
	dx.SendSms(in.Phone, strconv.Itoa(code))
	config.Rdb.Set(config.Ctx, CodeKey, code, time.Minute*60)
	//限制发送次数(5分钟)
	config.Rdb.Incr(config.Ctx, "send:smsNumber"+in.Phone)
	config.Rdb.Expire(config.Ctx, "send:smsNumber"+in.Phone, time.Minute*5)
	return &__.SendSmsResp{
		Success: true,
		Message: "验证码已发送,请前去查收",
	}, nil
}

// Register 用户注册
func (s *Server) Register(_ context.Context, in *__.RegisterReq) (*__.RegisterResp, error) {
	// 格式校验
	if in.Phone == "" || in.Password == "" || in.NewCode == "" {
		return nil, fmt.Errorf("参数不能为空")
	}

	//手机号格式校验
	if !regexp.MustCompile(`^1[3-9]\d{9}$`).MatchString(in.Phone) {
		return nil, fmt.Errorf("手机号格式不对,请重新输入")
	}

	//查询数据库
	var user model.User
	err := config.DB.Where("phone=?", in.Phone).First(&user).Error

	//获取验证码
	code, _ := config.Rdb.Get(config.Ctx, "SendSms:"+in.Phone).Result()
	if code != in.NewCode {
		return nil, fmt.Errorf("验证码错误或已过期")
	}

	if err == nil {
		return nil, fmt.Errorf("用户已注册,请前去登录")
	}

	user = model.User{
		Phone:    in.Phone,
		Password: md5.Md5(in.Password),
	}

	config.DB.Create(&user)
	return &__.RegisterResp{
		UserId: int64(user.ID),
	}, nil
}

// Login 用户登录
func (s *Server) Login(_ context.Context, in *__.LoginReq) (*__.LoginResp, error) {
	// 格式校验
	if in.Phone == "" || in.NewCode == "" {
		return nil, fmt.Errorf("参数不能为空")
	}

	//手机号格式校验
	if !regexp.MustCompile(`^1[3-9]\d{9}$`).MatchString(in.Phone) {
		return nil, fmt.Errorf("手机号格式不对,请重新输入")
	}

	//查询数据库
	var user model.User
	err := config.DB.Where("phone=?", in.Phone).First(&user).Error

	if err != nil {
		return nil, fmt.Errorf("用户未注册,请前去注册")
	}

	//获取验证码
	code, _ := config.Rdb.Get(config.Ctx, "SendSms:"+in.Phone).Result()
	if code != in.NewCode {
		return nil, fmt.Errorf("验证码错误或已过期")
	}

	token, _ := jwt.TokenHandler(strconv.Itoa(int(user.ID)))

	config.DB.Create(&user)
	return &__.LoginResp{
		UserId: int64(user.ID),
		Token:  token,
	}, nil
}
